// axios 二次封装
import axios, {
  type AxiosRequestConfig,
  AxiosResponse,
  AxiosError,
} from "axios";
import router from "@/router/";

import qs from "qs";

export const httpInstance = axios.create({
  timeout: 60000,
  withCredentials: true,
});

declare module "axios" {
  export interface AxiosResponse<T = any> extends Promise<T> {}
}
import { ElMessageBox, ElLoading } from "element-plus";

import "element-plus/theme-chalk/el-message.css";
import "element-plus/theme-chalk/el-message-box.css";
import "element-plus/theme-chalk/el-loading.css";
import { useLocaleStore } from "@/store/locales";
const useLocale = useLocaleStore();

interface InitConfig {
  isNeedLoading: boolean;
  
}

let loadingService:any = null,
  loadingRequestQueue:any = [];
// 默认接口配置

let initConfig :InitConfig= {
  isNeedLoading: true, // 是否需要loading
};
/*
 *根据环境变量区分接口的默认地址
 */
console.log(process.env.NODE_ENV);
// switch (process.env.NODE_ENV) {
//   case "production":
//     httpInstance.defaults.baseURL = "http://rap2api.taobao.org/app/mock/316849";
//     break;
//   case "development":
//     httpInstance.defaults.baseURL = "http://rap2api.taobao.org/app/mock/316849";
//     break;
//   default:
//     httpInstance.defaults.baseURL = "http://rap2api.taobao.org/app/mock/316849";
//     break;
// }
switch (process.env.NODE_ENV) {
  case "production":
    httpInstance.defaults.baseURL = "https://apifoxmock.com/m1/4938198-4595753-default";
    break;
  case "development":
    httpInstance.defaults.baseURL = "http://127.0.0.1:4523/m1/4938198-4595753-default";
    break;
  default:
    httpInstance.defaults.baseURL = "https://apifoxmock.com/m1/4938198-4595753-default";
    break;
}
/**
 * 设置超时时间和跨域时候是否允许携带凭证
 *
 */

//httpInstance.defaults.headers["content-Type"] = "application/json";
httpInstance.defaults.headers.post["Content-Type"] =
  "application/x-www-form-urlencoded";

// /*
/**设置请求拦截器
 *TOKEN校验（JWT） 接收服务器返回的token 存储到vuex/本地存储中（暂时没用）
 * 每一次向服务器发送请求，我们应该把token带上
 */
httpInstance.interceptors.request.use(
  (config: AxiosRequestConfig | any) => {
    config.headers["Lang"] = useLocale.locale;
    config.headers["User_id"] = useLocale.userid;
    let token = localStorage.getItem("token");
    if (token) {
      config.headers["Token"] = token;
    }
    const { method = "get" } = config;
    if (method === "post") {
      if (!config.data) {
        config.data = {};
      }
      if (config.submitType === "json") {
        config.headers["Content-Type"] = "application/json";
      } else {
        config.data = qs.stringify(config.data);
      }
    }

    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  }
);

// /**
//  * 响应拦截器
//  * 服务器返回信息  拦截 客户js获取
//  */

httpInstance.interceptors.response.use(
  (response: AxiosResponse) => {
    return response.data;
  },
  (error) => {
    let { response } = error;

    if (response) {
      //服务器起码返回结果了
      switch (response.status) {
        case 401: //当前用户未登录 权限
          ElMessageBox.alert("当前用户未登录", "提示", {
            confirmButtonText: "OK",
            type: "error",
          }).then(() => {
            router.replace({
              path: "/login",
              query: {
                redirect: router.currentRoute.value.fullPath,
              },
            });
          });
          break;
        case 402: //服务器已经理解请求，但是拒绝执行（一般是token过期）
          localStorage.removeItem("token");
          ElMessageBox.alert("token过期，请重新登陆", "提示", {
            confirmButtonText: "OK",
            type: "error",
          }).then(() => {
            router.replace({
              path: "/login",
              query: {
                redirect: router.currentRoute.value.fullPath,
              },
            });
          });

          break;
        case 403:
          ElMessageBox.alert("登录过期请重新登录", "提示", {
            confirmButtonText: "OK",
            type: "error",
          }).then(() => {
            router.replace({
              path: "/login",
              query: {
                redirect: router.currentRoute.value.fullPath,
              },
            });
          });
          break;
        case 404:
          router.replace({
            path: "/404",
          });
          break;
        default:
          ElMessageBox.alert("网络出错，请稍后再试", "提示", {
            confirmButtonText: "OK",
            type: "error",
          });
          break;
      }
    } else {
      ElMessageBox.alert("网络出错，请稍后再试", "提示", {
        confirmButtonText: "OK",
        type: "error",
      });
      return Promise.reject(error);
    }
  }
);

/**
 * 判断是否有接口还未加载完
 * @param {*} trackId
 */
function compareLoadingStatus(trackId:string) {
  const targetIndex = loadingRequestQueue.findIndex((item:string) => item === trackId);
  if (targetIndex > -1) {
    loadingRequestQueue.splice(targetIndex, 1);
  }
  if (loadingRequestQueue.length==0) {
    loadingService?.close();
  }
}

function getTrackId() {
  return `trackid${new Date().getTime()}_${(Math.random() * 100000).toFixed(
    0
  )}`;
}

//请求公共函数
function send(method = "get", url: string, data = {},options:any = {}) {
  options = {
    ...initConfig,
    ...options,
    trackId: getTrackId(),
  };
  if (options.isNeedLoading) {
    loadingRequestQueue.push(options.trackId);
    
      loadingService = ElLoading.service({
        lock: true,
        background: 'rgba(0, 0, 0, 0.4)',
      });
    
  }
  return new Promise((resolve, reject) => {
    httpInstance({
      method,
      url,
      [method === "get" ? "params" : "data"]: data,
    })
      .then((res) => {
        resolve(res);
      })
      .catch((error) => {
        reject(error);
      })
      .finally(() => {
       
        if (options.isNeedLoading) {
          compareLoadingStatus(options.trackId);
        }
      });
  });
}

export function $get(url: string, params = {}, options = {}) {
  return send("get", url, params, options);
}
export function $post(url: string, data = {}, options = {}) {
  return send("post", url, data, options);
}

// export const $get = (url: string, params?: object) => {
//   return httpInstance.get(url, { params });
// };
// export const $post = (url: string, params?: object) => {
//   return httpInstance.post(url, params);
// };
